import os.path

import h5py
import random
import pickle
import scipy.io
import numpy as np
import pandas as pd
import matplotlib.image
import statsmodels.api as sm
import matplotlib.pyplot as plt
from scipy.signal import savgol_filter

lowess = sm.nonparametric.lowess
path = "D:\PycharmProjects\My_project\kneepoint\kneepoint\Batch3Kneepoint.csv"
csvData = pd.read_csv(path, header=None)  # header=None是去掉表头部分
csvData = csvData.iloc[:, 0]
allKneePoint = np.array(csvData).astype(int)


def LoadQandV(filename):
    f = h5py.File(filename)
    list(f.keys())
    batch = f['batch']
    list(batch.keys())
    # num_cells = batch['summary'].shape[0]
    cell = [x for x in range(45)]
    random.shuffle(cell)
    All = []
    All_Qd = []
    All_v = []
    for o in cell[0:5]:
        cycles = f[batch['cycles'][o, 0]]
        # 先取第1个数据
        q_diff = []
        t_to_q = []
        ts = []
        Q_max = []
        kneePoint = allKneePoint[o]

        # 获取距离膝点超过或少于100的周期的数据
        # 随机获取膝点前的某个循环的数据
        r = random.random()
        if r >= 0.5:
            if kneePoint - 150 > 0:
                cycle = random.randint(20, kneePoint - 150)
            else:
                cycle = random.randint(kneePoint - 70, kneePoint)
        if r < 0.5:
            cycle = random.randint(kneePoint - 70, kneePoint)

        select_cycle = 500
        for i in range(select_cycle):
            # Qd放电容量
            Qd = np.hstack((f[cycles['Qd'][i, 0]][()]))
            # 时间
            t = np.hstack((f[cycles['t'][i, 0]][()]))
            # Qc = np.hstack((f[cycles['Qc'][i, 0]][()]))
            V = np.hstack((f[cycles['V'][i, 0]][()]))
            # I = np.hstack((f[cycles['I'][i, 0]][()]))
            # print("last: ", Qd.shape, V.shape)
            '''
            for d in range(Qd.shape[0]):
                if Qd[d] >= 0.0001:
                    print(d)
                    Qd = Qd[d:-1]
                    V = V[d:-1]
                    t = t[d:-1]
                    break
            '''
            Qd = Qd[len(Qd)-401:-1]
            V = V[len(V)-401:-1]
            t = t[len(t)-401:-1]

            for d in range(V.shape[0]):
                if V[d] <= 2.1:
                    V[d] = 2.1
            All_Qd.append(Qd)
            All_v.append(V)

            # 计算Q曲线
            '''
            for j in range(0, len(Qd) - 1):
                if Qd[j] != 0:
                    print("Enter!!!")
                    Q = np.hstack([np.transpose(Qc[0:i - 1, np.newaxis]), 1.1 - np.transpose(Qd[i:-1, np.newaxis])])
                    print(Q)
                    print("len_Q: ", len(Q[0]))
                    break
            '''
            Q = Qd
            # 有关时间
            for k in range(0, 600):
                # 最后一位
                t_max = t[-1]
                # 第一位
                t_min = t[0]
                # （最大-最小）/600
                tdev = (t_max - t_min) / 600
                # print("tdev: ", tdev)
                t_need = t[0] + tdev * k
                # 获取水平最小**的索引
                idx = (np.abs(t - t_need)).argmin()

                t_to_q.append(Q[idx])
                ts.append(t[idx])
                # qc.append(Qc[idx])
                # qd.append(Qd[idx])
                # t2v.append(V[idx])
                # t2i.append(I[idx])

                # print("************************************")
                # print("*********600, 第", k, "次结束***********")
                # print("************************************")
            Q_max.append(max(t_to_q))
            # plt.plot(Q_max[i], label='Q')
            # plt.show()
            # print("Q_Max: ", len(Q_max))
            t_to_q = []
        True_SoH = Q_max

        for i in range(int(select_cycle)):
            # qdiff = All_Qd[0] - All_Qd[i]
            # q_diff.append(qdiff)
            # v, ind = np.unique(All_v[i], return_index=True)
            # q, ind = np.unique(All_Qd[i], return_index=True)
            # plt.plot(All_Qd[i])
            # plt.plot(All_v[i], All_Qd[i])

            plt.plot(All_v[i], All_Qd[i])
            plt.xlabel('U(V)')
            plt.ylabel('Qd(Ah)')
            # print(All_Qd[0])
            # plt.xlim(2.2, 3.7)
            plt.grid()
        # plt.show()

        plt.figure()
        for i in range(int(select_cycle)):
            dy_dx = np.gradient(All_Qd[i], All_v[i])
            dy_dx[np.isnan(dy_dx)] = 0
            q_diff.append(dy_dx)
            plt.plot(All_v[i], q_diff[i])
            plt.xlabel('U(V)')
            plt.ylabel('IC(Ah/V)')
            plt.xlim(2.2, 3.7)
            plt.ylim(-8, 0.5)
            plt.grid()
        plt.show()
        All_v = []
        All_Qd = []
        # print("************************************")
        # print("*********", cycle, ", 第", i, "次循环结束***********")
        # print("************************************\n")

        print("************************************")
        print("*************电池cell结束*************")
        print("************************************")

        print("length_SoH: ", len(True_SoH))
        print("cell: ", o)
        print('r:' + str(r))
        print('cycle:' + str(cycle))
        print('knee:' + str(kneePoint))
        # x = np.linspace(len(Q_max))
        # plt.plot(ts[0: cycle], Q_max)

        # plt.plot(Q_max)
        # plt.ylabel('Q/(A·h)')
        # plt.xlabel('Time/(Min)')
        # plt.xlabel('cycles')
        # plt.grid()

        All.append(True_SoH)

        # plt.legend()
        # plt.grid()

        '''
        plt.figure()
        plt.plot(qc, label='charge')
        plt.plot(qd, label='discharge')
        plt.xlim(0, 600)
        plt.legend()
        plt.grid()

        plt.figure()
        plt.plot(t2i, label='Current')
        plt.plot(t2v, label='Voltage')
        plt.xlim(0, 1800)
        plt.legend()
        plt.grid()
        '''


        path = "D:\PycharmProjects\My_project\LSTM\\article"
        name1 = f"{o}_cell_label.txt"
        name2 = f"{o}_cell_QD.txt"
        name3 = f"{o}_cell_IC.txt"
        list_filename2 = os.path.join(path, name2)
        list_filename3 = os.path.join(path, name3)
        print(list_filename2)
        print(list_filename3)
        # np.savetxt(list_filename2, All_Qd, fmt='%.5f')
        # np.savetxt(list_filename3, q_diff, fmt='%.5f')

    '''
    plt.plot(All[0], label=f"{cell[0]}_cell")
    plt.plot(All[1], label=f"{cell[1]}_cell")
    plt.plot(All[2], label=f"{cell[2]}_cell")
    plt.plot(All[3], label=f"{cell[3]}_cell")
    plt.plot(All[4], label=f"{cell[4]}_cell")
    plt.legend()
    plt.grid()
    plt.show()
    '''
LoadQandV('2019-01-24_batchdata_updated_struct_errorcorrect.mat')
